package main

import (
	"context"
	"fmt"
	"time"

	clientv3 "go.etcd.io/etcd/client/v3"
)

func main() {
	cli, err := clientv3.New(clientv3.Config{
		Endpoints:   []string{"10.0.0.11:2379"},
		DialTimeout: 5 * time.Second,
	})
	if err != nil {
		// handle error!
		fmt.Println(err)
		return
	}
	defer cli.Close()

	// 实现 etcd 租约机制
	lease := clientv3.NewLease(cli)
	leaseGrant, err := lease.Grant(context.TODO(), 10)
	if err != nil {
		fmt.Println("lease grant failed: ", err)
		return
	}
	// 自动续租
	ctx, _ := context.WithTimeout(context.TODO(), 5*time.Second)

	keepRespChan, err := lease.KeepAlive(ctx, leaseGrant.ID)
	if err != nil {
		fmt.Println("keep Alive lease failed")
		return
	}

	// go func() {
	// 	for {
	// 		select {
	// 		case keepResp := <-keepRespChan:
	// 			if keepResp == nil {
	// 				fmt.Println("租约已经失效，即将过期")
	// 				goto END
	// 			} else {
	// 				fmt.Println("收到自动续期应答: ", keepResp.ID)
	// 			}
	// 		}
	// 	}
	// END:
	// }()

	go func() {
		for keepResp := range keepRespChan {
			fmt.Println("收到自动续期应答: ", keepResp.ID)
		}
		fmt.Println("租约已经失效，即将过期")
	}()

	// put 一个KV，让它与租约关联起来，从而实现10秒后自动过期
	resp, err := cli.Put(context.TODO(), "time", "10", clientv3.WithLease(leaseGrant.ID))
	if err != nil {
		fmt.Println("put failed: ", err)
		return
	}
	fmt.Println("写入成功： ", resp.Header.Revision)

	for {
		getResp, _ := cli.Get(context.TODO(), "time")
		if getResp.Count != 0 {
			fmt.Println("租约还未过期: ", getResp.Kvs)
		} else {
			fmt.Println("租约已经过期")
			break
		}
		time.Sleep(2 * time.Second)
	}
}
